package com.analyse.stock.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.analyse.stock.constant.ApiConstant;
import com.analyse.stock.constant.StockConstant;
import com.analyse.stock.mapper.StockKlineDailyMapper;
import com.analyse.stock.model.StockInfoModel;
import com.analyse.stock.model.StockKlineDailyModel;
import com.analyse.stock.service.IStockInfo;
import com.analyse.stock.service.IStockKlineDaily;
import com.analyse.stock.utils.HttpUtil;
import com.analyse.stock.utils.StockStringUtil;
import com.analyse.stock.vo.StockKlineVO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StockKlineDailyService extends ServiceImpl<StockKlineDailyMapper, StockKlineDailyModel> implements IStockKlineDaily {

    @Autowired
    private IStockInfo istockInfo;

    @Override
    public Integer pullStockKlineDailyHistoryByTsanghi(String stockCode) {
        List<StockInfoModel> stockList = istockInfo.getStockList(Sets.newHashSet(stockCode));
        if(CollUtil.isEmpty(stockList)){
            return 0;
        }
        List<Integer> years = StockStringUtil.getAllYear(ApiConstant.BEGIN_DATE);
        AtomicInteger total = new AtomicInteger(0);
        for(StockInfoModel model : stockList){
            List<StockKlineDailyModel> list = Lists.newArrayList();
            for(Integer year : years){
                String startDate = String.format("%s-01-01",year);
                String endDate = String.format("%s-12-31",year);
                String url = StrUtil.format(ApiConstant.KLINE_TSANGHI_DAY_URL,model.getCountryCode(),model.getStockCode(),startDate,endDate);
                String result = HttpUtil.sendGet(url,"application/json", StockConstant.UTF8,6000L);
                if(StringUtils.isBlank(result)){
                    continue;
                }
                JSONObject object = JSON.parseObject(result);
                if(object.getInteger("code") != 200){
                    continue;
                }
                StockKlineVO dataVO = StockStringUtil.getObject(object.getString("data"), StockKlineVO.class);
                StockKlineDailyModel model1 = StockKlineDailyModel.transStockKlineModel(dataVO);
                list.add(model1);
                super.saveBatch(list);
                total.getAndAdd(list.size());
            }
        }
        return total.get();
    }


    @Override
    public Integer pullStockKlineDailyHistoryByEastMoney(List<StockInfoModel> stockList) {
        if(CollUtil.isEmpty(stockList)){
            return 0;
        }
        String klineType = "101";
        List<Integer> years = StockStringUtil.getAllYear(ApiConstant.BEGIN_DATE);
        AtomicInteger total = new AtomicInteger(0);
        for(StockInfoModel model : stockList){
            for(Integer year : years) {
                String startDate = String.format("%s0101",year);
                String endDate = String.format("%s1231",year);
                this.getKlineData(klineType, startDate,endDate, total, model);
            }
        }
        return total.get();
    }

    private void getKlineData(String klineType, String startDate,String endDate, AtomicInteger total, StockInfoModel model) {
        try{
            long time = System.currentTimeMillis()*1000;
            String url = StrUtil.format(ApiConstant.KLINE_URL,
                    startDate,endDate,String.format("%s.%s",model.getMarkCode(),model.getStockCode()),klineType,time);
            String result = HttpUtil.sendGet(url,"*/*", StockConstant.UTF8,6000L);
            if(StringUtils.isBlank(result)){
                return;
            }
            JSONObject object = JSON.parseObject(result);
            if(Objects.isNull(object) || Objects.isNull(object.getJSONObject("data")) ||
                    StringUtils.isBlank(object.getJSONObject("data").getString("klines"))){
                return;
            }
            JSONArray array = JSON.parseArray(object.getJSONObject("data").getString("klines"));
            if(Objects.isNull(array) || array.size()<1){
                log.info("## 股票:{}, {}没有:{}-{} 的日K数据",model.getStockCode(),model.getStockName(),startDate,endDate);
                return;
            }
            log.info("## 股票:{}, {} 开始解析:{}-{} 的日K数据",model.getStockCode(),model.getStockName(),startDate,endDate);
            List<StockKlineDailyModel> modes = Lists.newArrayList();
            for(Object vo : array){
                String[] str = vo.toString().split(StrUtil.COMMA);
                StockKlineDailyModel monthlyModel = StockKlineDailyModel.transStockKlineModel(str,model.getStockCode());
                modes.add(monthlyModel);
            }
            super.saveBatch(modes);
            total.getAndAdd(modes.size());
        }catch (Exception ex){
            log.error("## 股票:{}, {} 获取日K线,异常error：{}",model.getStockCode(),model.getStockName(),ex.getMessage(),ex);
        }
    }

    @Override
    public Integer pullLatest(List<StockInfoModel> stockList,String date){
        if(CollUtil.isEmpty(stockList)){
            return 0;
        }
        String klineType = "101";
        date = date.replaceAll("-","");
        AtomicInteger total = new AtomicInteger(0);
        for(StockInfoModel model : stockList){
            this.getKlineData(klineType, date,date, total, model);
        }
        return total.get();
    }

    @Override
    public List<StockKlineDailyModel> getStockKlineDailyList(String stockCode, String startDate,String endDate){
        LambdaUpdateWrapper<StockKlineDailyModel> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(StockKlineDailyModel::getStockCode,stockCode);
        wrapper.ge(StockKlineDailyModel::getTradeDate,startDate);
        List<StockKlineDailyModel> list = super.list(wrapper);
        if(CollUtil.isEmpty(list)){
            return Lists.newArrayList();
        }
        //升序排列
        return list.stream().sorted(Comparator.comparing(StockKlineDailyModel::getTradeDate)).collect(Collectors.toList());
    }
}
